package com.ezlcp.form.db;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson2.JSONObject;
import com.ezlcp.form.entity.Entity;
import com.ezlcp.form.entity.EntityIndex;
import com.github.drinkjava2.jdialects.model.TableModel;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.Map;

/**
 * @author Elwin ZHANG
 * 数据库操作的接口<br />
 * @date 2023/7/6 15:53
 */
public interface IDbClient {

    /***
     * 获取当前对象的数据源
     * @return com.alibaba.druid.pool.DruidDataSource
     * @author Elwin ZHANG
     * @date 2023/7/13 16:12
     */
    DruidDataSource getDataSource();

    /***
     *  获取当前对象的JdbcTemplate
     * @return org.springframework.jdbc.core.JdbcTemplate
     * @author Elwin ZHANG
     * @date 2023/7/13 16:11
     */
    JdbcTemplate getJdbcTemplate();

    /***
     *  判断实体对应的表（视图）是否存在
     * @param entity 实体对象
     * @return int 0不存在，1存在无数据，2 存在且有数据
     * @author Elwin ZHANG
     * @date 2023/7/6 16:49
     */
    int existTable(Entity entity);

    /***
     *  创建表
     * @param entity 实体对象
     * @return java.lang.String
     * @author Elwin ZHANG
     * @date 2023/7/6 16:51
     */
    boolean createTable(Entity entity);

    /***
     *  删除实休对应的物理表
     * @param entity 实体对象
     * @return boolean
     * @author Elwin ZHANG
     * @date 2023/7/6 17:07
     */
    boolean dropTable(Entity entity);

    /***
     *  获取删除表的SQL
     * @param entity 实体
     * @return java.lang.String
     * @author Elwin ZHANG
     * @date 2023/7/14 10:31
     */
    String dropTableSql(Entity entity);

    /***
     *  获取表结构变化的SQL语句
     * @param entity 实体对象
     * @return java.util.List<java.lang.String>
     * @author Elwin ZHANG
     * @date 2023/7/14 10:49
     */
    String[] alterTableSql(Entity entity);

    /***
     *  根据表名获取数据库中定义信息
     * @param tableName 物理表名
     * @return com.github.drinkjava2.jdialects.model.TableModel
     * @author Elwin ZHANG
     * @date 2023/7/14 14:46
     */
    TableModel getTableModel(String tableName);

    /***
     *  检查SQL语句数组中是否含用drop命令
     * @param sqlArray sql数组
     * @return boolean
     */
    boolean containDropSql(String[] sqlArray);

    /***
     *  执行多个SQL语名
     * @param sqlArray Sql数组
     */
    void executeSql(String[] sqlArray);

    /***
     *  删除表索引
     * @param indexName 索引名
     * @param tableName 表名
     */
    void dropIndex(String indexName, String tableName);

    /***
     *  创建索引
     * @param index 索引对象
     * @param tableName 表名
     */
    void createIndex(EntityIndex index, String tableName);

    /***
     * 根据主键查询表单记录
     * @param tableName 物理表名
     * @param pkId 记录ID
     * @return java.util.Map<java.lang.String, java.lang.Object>
     */
    Map<String, Object> getById(String tableName, String pkId);

    /***
     * 根据主键逻辑删除表单记录
     * @param tableName 物理表名
     * @param pkId 记录ID
     * @return boolean
     */
    boolean tombstoneById(String tableName, String pkId);

    /***
     * 根据主键物理删除表单记录
     * @param tableName 物理表名
     * @param pkId 记录ID
     * @return boolean
     */
    boolean deleteById(String tableName, String pkId);

    /***
     * 新增实体表相关的记录
     * @param entity 实体对象，包括字段列定义
     * @param record 记录数据
     */
    boolean insert(Entity entity, JSONObject record);

    /***
     * 修改实体表相关的记录
     * @param entity 实体对象，包括字段列定义
     * @param record 记录数据
     * @param pkId 主键值
     */
    boolean update(Entity entity, JSONObject record, String pkId);

    /***
     * 将通用的SQL转换成当前数据库的SQL
     * @param sql 通用SQL
     * @return java.lang.String
     */
    String convert2Native(String sql);

    /***
     * 获取分页查询SQL
     * @param sql 查询语句（未分页）
     * @param pageNo 页码
     * @param pageSize 每页记录数
     * @return java.lang.String
     */
    String getPagedSql(String sql, int pageNo, int pageSize);
}